package components.editor
{
	import UIFree.ObjectEvent;
	import UIFree.command.uif_commandManager;
	import UIFree.components.uif_window;
	import UIFree.uif_component;
	
	import UIUtils.Exif.ExifHeader;
	import UIUtils.uif_util;
	
	import classes.Commands.c_applyFilterCommand;
	import classes.Commands.c_applyHistoryData;
	import classes.Commands.c_assignMaskElement;
	import classes.Commands.c_createMaskCommand;
	import classes.Commands.c_cropCommand;
	import classes.Commands.c_deleteAll;
	import classes.Commands.c_duplicateCommand;
	import classes.Commands.c_flipCommand;
	import classes.Commands.c_holeSelectCommand;
	import classes.Commands.c_insertBitmapCommand;
	import classes.Commands.c_insertEffectCommand;
	import classes.Commands.c_insertInHoleCommand;
	import classes.Commands.c_insertMaskCommand;
	import classes.Commands.c_insertTextCommand;
	import classes.Commands.c_mergeToBitmap;
	import classes.Commands.c_multylayerDivideCommand;
	import classes.Commands.c_newMultiLayerCommand;
	import classes.Commands.c_openMultiLayerCommand;
	import classes.c_events;
	import classes.c_imageTypes;
	import classes.c_layerAdjustDialogs;
	import classes.c_layerAdjustType;
	import classes.c_locale;
	import classes.c_uiEvents;
	
	import components.dialogs.c_childListDialog;
	import components.dialogs.c_elementPropDlg;
	import components.dialogs.c_layersDialog;
	import components.dialogs.c_mlpDialog;
	import components.dialogs.c_propertyDialog;
	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.filters.BitmapFilter;
	import flash.geom.Point;
	import flash.utils.ByteArray;
	
	public class c_baseCollagesEditor extends c_baseEditor {
		private static const AJUST	: String = 'ajust'; 
		private static const EFFECT	: String = 'effect';
		
		private var _toolDialogs	: Object;
		public function c_baseCollagesEditor(parent:uif_component) {
			super(parent);
			_toolDialogs = {};
		}
		
		override protected function listenEvents():void {
			super.listenEvents();
			addEvent(c_events.IMAGELOADCOMPLETE, doImageLoadComplete, workspace);
			addEvent(c_events.APPLYFILTER, doApplyFilter, workspace);
			addEvent(c_imageTypes.MLPDATACOMPLETE, doMPLDataComplete, workspace);
//			addEvent(MouseEvent.MOUSE_DOWN, doMouseDown, stage);
		}
		
		override protected function listenUIEvents(): void {
			super.listenUIEvents();
			addEvent(c_uiEvents.MERGEIMAGES, doMergeImages, workspace);
			addEvent(c_uiEvents.MERGETOMULTILAYER, doMergeMultiLayer, workspace);
			addEvent(c_uiEvents.MULTILAYERDIVIDE, doMultiLayerDivide, workspace);
			addEvent(c_uiEvents.TEXTINSERT, doTextInsert, workspace);
			addEvent(c_uiEvents.EFFECTINSERT, doEffectInsert, workspace);
			addEvent(c_uiEvents.CLEARALL, doClearAll, workspace);
			addEvent(c_uiEvents.LAYERLIST, doLayerList, workspace);
			addEvent(c_uiEvents.ASMASK, doAsMask, workspace);
			addEvent(c_uiEvents.DUPLICATE, doDuplicate, workspace);
			addEvent(c_uiEvents.LAYERADJUST, doLayerAdjust, workspace);
			addEvent(c_uiEvents.LAYEREFFECT, doLayerEffect, workspace);
			addEvent(c_uiEvents.OPENFILEMASK, doOpenMask, workspace);
			addEvent(c_uiEvents.MASKINSERT, doMaskInsert, workspace);
			addEvent(c_uiEvents.SWAPHORY, doSwaphory, workspace);
			addEvent(c_uiEvents.SWAPVERT, doSwapvert, workspace);
			addEvent(c_uiEvents.CLIPMODE, doClipmode, workspace);
			addEvent(c_uiEvents.CROPOUTSIDE, doCropoutside, workspace);
			addEvent(c_uiEvents.CROPINSIDE, doCropinside, workspace);
		}
		
		public function getValueEvent(event: String, options: Object=null): Object {
			var obj: Object = uif_util.union({
				result: null
			}, options);
			workspace.dispatchEvent(new ObjectEvent(event, obj));
			return obj.result;
		}
		
		protected function initToolDialog(toolName: String, createFunc: Function, closeFunc: Function=null): void {
			if (_toolDialogs[toolName]) {
				if (closeFunc != null) _toolDialogs[toolName].close(0, closeFunc);
			} else {
				_toolDialogs[toolName] = createFunc();
				_toolDialogs[toolName].addEvent(uif_window.CLOSEWINDOW, function(e: Event): void {
					delete(_toolDialogs[toolName]);
				});
			}			
		}
		
		protected function layerAdjust(layer: c_baseElement, toolName: String, object: Object): void {
			if (c_layerAdjustDialogs.compatibility(object.type, layer)) {
				initToolDialog(toolName, function(): c_propertyDialog {
					return new (c_layerAdjustDialogs.get(object.type))(cl.dialogLayer, layer, object.caption);
				}, function(): void {
					layerAdjust(layer, toolName, object);
				});
			}
		}
		
		protected function insertAsLayer(source: DisplayObject, params: Object=null): void {
			
			function insertAsBitmap(): void {
				executeCommand(new c_insertBitmapCommand(This, uif_util.EnterHere(getNewElementMaxRect(), new Point(source.width, source.height)), source, true, params));
			}
			
			var _holesElement: c_holeyElement = dragRect.link as c_holeyElement;
			var bme: c_bitmapMaskElement = (dragRect.link as c_bitmapMaskElement);
			if (!bme && dragRect.link && dragRect.link.owner && (dragRect.link.owner is c_bitmapMaskElement))
				bme = (dragRect.link.owner as c_bitmapMaskElement);
			
			if (bme && params) {
				executeCommand(new c_assignMaskElement(This, bme, source, params));
			} else {
				if (_holesElement) {
					cl.question(locale.INHOLEQUESTION, function(): void {
						executeCommand(new c_insertInHoleCommand(_holesElement, source));
					}, insertAsBitmap, locale.WARNING);
				} else insertAsBitmap();
			}
		}

//Обработка комманд		
		protected function doAsMask(e: Event): void {
			var element: c_baseElement = dragRect.link as c_baseElement;
			if (element) executeCommand(new c_createMaskCommand(This, element));
		}
		
		protected function doOpenMask(e: Event): void {
			openFileDialog(function(a_data: ByteArray, a_fileType: String): void {
				c_imageTypes.baToBmd(a_data, function(bmd: BitmapData): void {
					maskInsert(new Bitmap(bmd), null);
					bmd.dispose();
				});
			});
		}
		
		private function maskInsert(bmp: Bitmap, a_params: Object): void {
			executeCommand(new c_insertMaskCommand(This, bmp, a_params));
		}
		
		protected function doMaskInsert(e: ObjectEvent): void {
			maskInsert(e.object.bitmap, e.object.params);
		}
		
		protected function doSwaphory(e: ObjectEvent): void {
			if (currentImage is c_bitmapElement) 
				executeCommand(new c_flipCommand(This, currentImage as c_bitmapElement, true));
		}
		
		protected function doSwapvert(e: ObjectEvent): void {
			if (currentImage is c_bitmapElement) 
				executeCommand(new c_flipCommand(This, currentImage as c_bitmapElement, false));
		}
		
		protected function doClipmode(e: Event): void {
			if (currentImage)
				dragRect.nodragMode = !dragRect.nodragMode; 
		}
		
		protected function doCropoutside(e: Event): void {
			if (currentImage is c_bitmapElement) 
				executeCommand(new c_cropCommand(This, currentImage as c_bitmapElement, true));
		}
		
		protected function doCropinside(e: Event): void {
			if (currentImage is c_bitmapElement) 
				executeCommand(new c_cropCommand(This, currentImage as c_bitmapElement, false));
		}
		
		protected function doDuplicate(e: Event): void {
			var element: c_bitmapElement = dragRect.link as c_bitmapElement;
			if (element) executeCommand(new c_duplicateCommand(This, element));
		}
		
		protected function doLayerList(e: Event): void {
			initToolDialog('layers', function(): c_propertyDialog {
				var dlg: c_childListDialog;
				if (currentImage is c_multiLayerElement)
					dlg = new c_mlpDialog(cl.dialogLayer, currentImage as c_multiLayerElement, locale.LAYERS);
				else dlg = new c_layersDialog(cl.dialogLayer, This, locale.LAYERS); 
				return dlg;
			});
		}
		
		protected function doLayerAdjust(e: ObjectEvent): void {
			var selected: c_baseElement = cl.getValueEvent(c_events.GETSELECTED) as c_baseElement;
			if (selected) layerAdjust(selected, AJUST, e.object);
		}
		
		protected function doLayerEffect(e: ObjectEvent): void {
			var selected: c_baseElement = cl.getValueEvent(c_events.GETSELECTED) as c_baseElement;
			if (selected) layerAdjust(selected, EFFECT, e.object);
		}
		
		protected function doImageLoadComplete(e: ObjectEvent): void {
			insertAsLayer(e.object.image, e.object.params);
		}
		
		protected function doMPLDataComplete(e: ObjectEvent): void {
			executeCommand(new c_openMultiLayerCommand(this, e.object as Array));
			//insertAsLayer(e.object as DisplayObject);
		}
		
		protected function doMergeImages(e: Event): void {
			executeCommand(new c_mergeToBitmap(this));
//			insertAsLayer(new Bitmap(paintFromBitmap(true)));
		}
		
		protected function executeAfterCloseDlgAll(func: Function): void {
			if (c_elementPropDlg.count() > 0) {
				function doElemDlgList(e: ObjectEvent): void {
					if (e.object.length == 0) {
						func();
						cl.workspace.removeEventListener(c_events.ELEMDLGLIST, doElemDlgList);
					}
				}
				cl.workspace.addEventListener(c_events.ELEMDLGLIST, doElemDlgList);
				cl.workspace.dispatchEvent(new Event(c_events.ELEMDLGCLSEALL));
			} else func();
		}
		
		protected function doMergeMultiLayer(e: Event): void {
			const DEFAULTDEPTH: int = 50;
			
			var bitmaps: Array = getBitmaps(true);
			if (bitmaps.length > 1) {
				executeAfterCloseDlgAll(function(): void {
					executeCommand(new c_newMultiLayerCommand(This, bitmaps, DEFAULTDEPTH));
				});
			} else cl.alert(locale.WARNING, locale.FEWLAYERS);
		}
		
		protected function doMultiLayerDivide(e: Event): void {
			var mlElement: c_multiLayerElement = currentImage as c_multiLayerElement;
			if (mlElement) executeCommand(new c_multylayerDivideCommand(This, mlElement));
		}
		
		protected function doApplyFilter(e: ObjectEvent): void {
			if (currentImage)
				executeCommand(new c_applyFilterCommand(currentImage, e.object as BitmapFilter));
		}
		
		protected function doTextInsert(e: ObjectEvent): void {
			executeCommand(new c_insertTextCommand(this));
		}
		
		protected function doEffectInsert(e: ObjectEvent): void {
			executeCommand(new c_insertEffectCommand(this));
			layerAdjust(currentImage, AJUST, {
				type	: c_layerAdjustType.EFFECT,
				caption	: locale.ANIMPARAMS
			});
		}
		
		protected function doClearAll(e: Event): void {
			if (imageLayer.numChildren > 0) executeCommand(new c_deleteAll(this));
		}
		
/*		
		protected function doMouseDown(e: MouseEvent): void {
			var target: DisplayObject = e.target as DisplayObject;
			checkAndSelectObject(target);
			//			if (target is c_baseElement) checkAndSelectElement();
		}
*/		
	}
}